<template>
  <div class="allocResource">
    <el-card>
      <div class="roleList" v-for="(item, index) in roleResourceList" :key="item.id">
        <el-row style="background:#f2f6fc" class="top">
          <el-col :span="24">
            <el-checkbox
              :indeterminate="isIndeterminate[index]"
              v-model="checkAll[index]"
              @change="handleCheckAllChange($event, item, index)">
                {{item.name}}
            </el-checkbox>
          </el-col>
        </el-row>
        <el-row>
          <!-- 在el-checkbox-group的v-model是不支持接收 {} 的 -->
          <!-- 在vue深入响应式原理可以找到答案 -->
          <el-checkbox-group
            v-model="checkedList[index]"
            @change="handleCheckedChange($event, item, index)">
            <el-col :span="8"
              v-for="role in item.resourceList"
              :key="role.id">
              <el-checkbox :label="role.id">
                {{role.name}}
              </el-checkbox>
            </el-col>
          </el-checkbox-group>
        </el-row>
      </div>
      <div class="btn">
        <el-button size="small" @click="resetChecked">清空</el-button>
        <el-button size="small" type="primary" @click="onSave">保存</el-button>
      </div>
    </el-card>
  </div>
</template>

<script>
import { getRoleResources, allocateRoleResources } from '@/services/resource'
export default {
  name: 'allocResource',
  props: {
    id: {
      type: [Number, String],
      require: true
    }
  },
  data () {
    return {
      // 数据列表
      roleResourceList: [],
      // 是否全选
      checkAll: {},
      // 被选中的角色资源管理(存储的是label绑定的role.id值)
      checkedList: {},
      roleResourceLength: 0,
      isIndeterminate: {}
    }
  },
  created () {
    this.getRoleResources()
  },
  mounted () {
  },
  methods: {
    // 获取角色资源列表
    async getRoleResources () {
      const { data } = await getRoleResources({
        roleId: this.id
      })
      if (data.code === '000000') {
        // 1. 得到基本页面结构数据
        this.roleResourceList = data.data
        // 在 Checkbox-group中 v-model 默认绑定类型是数组
        // 但是, 当每组数据都存储在一个大数组里面,不方便拿取每组数据进行处理
        // 所以, 想的是改变 v-model 绑定类型为对象,实现每组单独存储,再存储到一个大对象里面
        for (const index in this.roleResourceList) {
          this.$set(this.checkedList, index, [])
          this.$set(this.isIndeterminate, index, false)
        }
        // 2. 将数据遍历到视图页面
        this.getroleResource(data.data)
        // 3. 处理isIndeterminate 和 checkAll 的显示
        this.getShow(data.data)
      }
    },
    // 渲染数据
    getroleResource (resource) {
      resource.forEach((item, index) => {
        if (item.resourceList) {
          const resourceList = item.resourceList
          resourceList.forEach(i => {
            if (i.selected) {
              // 存在被选中的项
              // 1.将被选项添加到checkedList所在的index项中
              // this.checkedList[index].push(i.id)  //会造成数组里的数据频繁切换,而导致无法正常显示数据
              this.checkedList[index] = [...this.checkedList[index], i.id]
            }
          })
        }
      })
    },
    getShow (resource) {
      resource.map((item, index) => {
        // 如果当前项存在resourceList
        if (item.resourceList) {
          // 而当前项的checkedList(被选中项)长度 与自身长度一致,则父项被选中
          if (this.checkedList[index].length === item.resourceList.length) {
            this.checkAll[index] = true
          } else {
            // 当前项的checkedList(被选中项)长度 与自身长度不一致
            if (!this.checkedList[index].length) {
              // 当前被选中项的数组为空,indeterminate 为flse
              this.isIndeterminate[index] = false
            } else {
              this.isIndeterminate[index] = true
            }
          }
        }
      })
    },
    // 4. 全选的操作
    handleCheckAllChange (val, item, index) {
      item.resourceList.forEach(i => {
        if (i.selected !== val) {
          i.selected = val
          if (val) {
            this.checkedList[index] = [...this.checkedList[index], i.id]
          } else {
            this.checkedList[index] = []
          }
        }
      })
      this.isIndeterminate[index] = false
    },
    // 5. 选则单个的处理方式
    handleCheckedChange (id, item, index) {
      const checkedCount = this.checkedList[index].length
      this.checkAll[index] = checkedCount === item.resourceList.length
      this.isIndeterminate[index] = checkedCount > 0 && checkedCount < item.resourceList.length
    },
    // 6. 清空所有选项
    resetChecked () {
      Object.keys(this.checkedList).map(key => {
        // Object.keys(this.checkedList) 得到该对象的 index 值
        // this.checkedList[key] 通过map遍历index值, 并传给this.checkedList[key],得到该对象中每个数组的具体值
        this.checkedList[key] = []
        this.checkAll[key] = []
        this.isIndeterminate[key] = false
      })
    },
    // 7. 保存数据
    async onSave () {
      const resourceIdList = []
      for (let i = 0; i < this.roleResourceList.length; i++) {
        resourceIdList.push(...this.checkedList[i])
      }
      const { data } = await allocateRoleResources({
        roleId: this.id,
        resourceIdList
      })
      if (data.code === '000000') {
        this.$message.success('资源分配成功')
        this.$router.push({ name: 'role' })
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.roleList{
  border: 1px solid #dcdfe6;
  .el-row{
    padding: 20px;
  }
  .top{
    border-bottom: 1px solid #dcdfe6;
  }
}
.roleList:nth-child(n+2){
  border-top: 0 none;
}
.btn {
  margin-top: 15px;
  display: flex;
  justify-content: center;
}
</style>
